import React from 'react'
import PropTypes from 'prop-types'
import { Input, Button, Select } from 'antd'
import { observable, computed } from 'mobx'
import { observer } from 'mobx-react'

const { Option } = Select

import st from './index.scss'

@observer
export class InputItem extends React.Component {
  static propTypes = {
    attr: PropTypes.object,
    value: PropTypes.any,

    onChange: PropTypes.func
  }

  @observable attr = null

  componentDidMount() {
    const { attr } = this.props
    this.attr = attr
  }

  onChange(value) {
    const { onChange } = this.props

    onChange && onChange(value)
  }

  render() {
    const { value } = this.props

    if (!this.attr) {
      return null
    }

    switch (this.attr.type) {
      case 'password':
      case 'string':
        return (
          <Input
            type={this.attr.type}
            value={value}
            placeholder={this.attr.placeholder || ''}
            onChange={(e) => this.onChange(e.target.value)}
          />
        )
      case 'indexof':
        return (
          <Select onChange={this.onChange.bind(this)}>
            {this.attr.alternatives.map((obj, idx) => (
              <Option key={idx} value={obj.value}>
                {obj.name}
              </Option>
            ))}
          </Select>
        )
      default:
        return (
          <Input
            value={value}
            placeholder={this.attr.placeholder || ''}
            onChange={(e) => this.onChange(e.target.value)}
          />
        )
    }
  }
}

@observer
export default class Filter extends React.Component {
  static propTypes = {
    schema: PropTypes.object,

    onChange: PropTypes.func,
    onSearch: PropTypes.func
  }

  static defaultProps = {
    schema: {}
  }

  @observable attr = null
  @computed get attr_list() {
    if (this.attr === null) {
      return []
    }
    return [...this.attr.values()]
  }

  componentDidMount() {
    const { schema } = this.props
    const { attriutes, show_rule } = schema

    if (attriutes) {
      let attr = attriutes
      // 如果有search的规则
      if (show_rule && 'search' in show_rule) {
        attr = attriutes.filter(
          (attr) => show_rule.search.indexOf(attr.name) !== -1
        )
        const attr_obj = new Map()
        attr.forEach((atr) => {
          attr_obj.set(atr.name, atr)
        })
        this.attr = attr_obj
      }
    } else {
      console.warn('schema.attriutes is undefined')
    }
    this.onSearch()
  }

  onChange(atr_name, value) {
    const { onChange } = this.props

    const n_map = new Map(this.attr)
    const atr = n_map.get(atr_name)
    atr.value = value
    n_map.set(atr_name, atr)
    this.attr = n_map

    onChange && onChange(this.attr_list)
  }

  onSearch() {
    const { onSearch } = this.props

    onSearch && onSearch(this.attr_list)
  }

  render() {
    if (this.attr === null) {
      return null
    }

    return (
      <div className={st['box']}>
        {this.attr_list.map((atr) => (
          <InputItem
            key={atr.name}
            attr={atr}
            value={atr.value}
            onChange={(value) => this.onChange(atr.name, value)}
          />
        ))}
        <Button type="primary" onClick={this.onSearch.bind(this)}>
          搜索
        </Button>
      </div>
    )
  }
}
